package listener

import (
	"fabric-explorer/entity"
	"fabric-explorer/service"
	"fabric-explorer/tools"
	"fmt"
	"time"

	"go.mongodb.org/mongo-driver/bson"
)

const (
	NEW_BLOCK_EVENT_NAME = "New Block"
	NODE_ORDER           = "order"
	CHAINOCDE            = "asset_transfer"
)

//监听区块事件
func BlockEventLinstener() {
	eventClient, sdk, err := tools.GetEventClient()
	defer sdk.Close()
	if err != nil {
		fmt.Println(err)
		return
	}

	register, notifier, err := eventClient.RegisterBlockEvent()
	if err != nil {
		fmt.Printf("failed to register chaincode event,err:%v", err)
		return
	}
	defer eventClient.Unregister(register)

	for {
		select {
		case blockevent := <-notifier:
			fmt.Println("-------------received block event-----------------")
			fmt.Printf("blockevent.SourceURL: %v\n", blockevent.SourceURL)
			fmt.Printf("blockevent.Block.Header.Number: %v\n", blockevent.Block.Header.Number)
			event := entity.Event{
				Type:      entity.EVENT_TYPE_BLOCK,
				BlockNum:  blockevent.Block.Header.Number,
				EventName: NEW_BLOCK_EVENT_NAME,
				SourceURL: blockevent.SourceURL,
				NodeName:  NODE_ORDER,
				ChannelId: tools.ChannelID,
			}
			addEventData(event)
			//更新区块数据
			service.UpdateBlockData()
		case <-time.After(time.Second * 60):
			fmt.Println("waiting for block event")
			//return
		}
	}

}

//监听链码事件
func ChannelEventLinstener() {
	eventClient, sdk, err := tools.GetEventClient()
	defer sdk.Close()
	if err != nil {
		fmt.Println(err)
		return
	}

	registration, notifier, err := eventClient.RegisterChaincodeEvent(CHAINOCDE, "[a-zA-Z0-9_-]+")
	if err != nil {
		fmt.Printf("failed to register chaincode event,err:%v", err)
		return
	}
	defer eventClient.Unregister(registration)

	for {
		select {
		case ccEvent := <-notifier:
			fmt.Println("-------------received chaincode event-----------------")
			fmt.Printf("ccEvent.EventName: %v\n", ccEvent.EventName)
			fmt.Printf("ccEvent.ChaincodeID: %v\n", ccEvent.ChaincodeID)
			fmt.Printf("ccEvent.SourceURL: %v\n", ccEvent.SourceURL)
			fmt.Printf("ccEvent.BlockNumber: %v\n", ccEvent.BlockNumber)
			event := entity.Event{
				Type:      entity.EVENT_TYPE_CHAINCODE,
				BlockNum:  ccEvent.BlockNumber,
				SourceURL: ccEvent.SourceURL,
				EventName: ccEvent.EventName,
				Chaincode: ccEvent.ChaincodeID,
				NodeName:  tools.GetNodeNameByUrl(ccEvent.SourceURL),
				ChannelId: tools.ChannelID,
			}
			addEventData(event)
		case <-time.After(time.Second * 60):
			fmt.Println("waiting for chaincode event")
			//return
		}
	}
}

//添加事件到eventList
func addEventData(event entity.Event) {
	event.Timestamp = time.Now().UnixMilli()
	length := service.GetEventkNum(bson.D{})
	event.Num = length
	//前插
	service.InsertEvent(event)
}
